<script setup>
//引入静态数据
//wallType是一个对象，用来存储照片墙与留言墙的标题与标题下横签的数据
//label是一个数组，用来存储标签的名称
//none是一个对象，用来存储当页面没有数据时的提示信息
import { wallType, label, none } from "../utils/data.js";
//前期mock测试数据，后期删除
// import { note, photo } from "../../mock/index.js";

//引入页面组件
//NoteCard是一个组件，用来渲染留言卡片内容
import NoteCard from "../components/NoteCard.vue";
//AddModal是一个组件，用来渲染添加卡片、卡片详情、图片详情的弹窗
import AddModal from "../components/AddModal.vue";
//NewCard是一个组件，用来渲染添加卡片、上传卡片的弹窗内容
import NewCard from "../components/NewCard.vue";
//CardDetail是一个组件，用来渲染卡片详情的内容
import CardDetail from "../components/CardDetail.vue";
//PhotoCard是一个组件，用来渲染照片卡片内容
import PhotoCard from "../components/PhotoCard.vue";
//Viewer是一个组件，用来渲染点击照片后的图片放大界面的内容
import Viewer from "../components/Viewer.vue";


//引入lottie动画
import lottie from "lottie-web";
import loading from "../assets/images/loading.json";

//引入vue的方法
import { ref, onMounted, onUnmounted, computed, watch, nextTick } from "vue";
//引入路由的方法
import { useRoute } from "vue-router";
//引入api接口
//findWallPageApi是一个接口，用来获取留言墙或照片墙的卡片数据
import { findWallPageApi } from "../api/index.js";
//引入pinia的store
import { useUserIdStore } from "../stores/user.js";

const userIdStore = useUserIdStore();
const route = useRoute();

//这个id是从//wallmessage路由参数中获取的，用来控制渲染不同的页面
//id=0时渲染留言墙页面，id=1时渲染照片墙页面
const id = computed(() => {
  return Number(route.query.id);
});


onMounted(() => {
  scrollBottom();
  noteWidth();
  Loading();
  // 只加载当前页面类型的数据
    getWallCard();
    getPhotoCard();
  //监听页面宽度变化，重新计算放置卡片的空间盒子的外边距
  window.addEventListener("resize", noteWidth);
  //监听滚动条的变化，当add按钮与底部栏重叠时,上调add按钮的位置，始终保持add按钮在底部栏上面
  window.addEventListener("scroll", scrollBottom);
});
onUnmounted(() => {
  window.removeEventListener("resize", noteWidth); // 明确清理
  window.removeEventListener("scroll", scrollBottom); // 明确清理
});
//notes是用来存储便签数据的数组，初始值为空数组
const notes = ref([]);
//获取用户ip地址
const user = computed(() => {
  return userIdStore.user;
});
//监听user是否有值，有值则获取数据
//这个函数用来获取留言墙的卡片数据
// 在文件顶部定义两个独立的页码变量
const wallPage = ref(1); // 留言墙页码
const photoPage = ref(1); // 照片墙页码
const pagesize = 14; // 每页数量可以共用

// 修改getWallCard函数
const getWallCard = () => {
  if (wallPage.value > 0) {
    isLoading.value = -1;
    let data = {
      type: 0,
      page: wallPage.value, // 使用wallPage
      pagesize: pagesize,
      userId: user.value,
      label: numberlabel.value,
    };
    findWallPageApi(data).then((res) => {
      notes.value = notes.value.concat(res.message);
      console.log('notes', notes.value);
      if (res.message.length) {
        wallPage.value++; // 更新wallPage
      } else {
        wallPage.value = 0;
        isNotesLoading.value = 2;
      }
      if (isLoading.value !== 2) {
        if (notes.value.length > 0) {
          isLoading.value = 1;
        } else {
          isLoading.value = 0;
        }
      }
    });
    
  }
};

//
const photoArr = ref([]);
const photos = ref([]);
const getPhotoArr = () => {
  photoArr.value = [];
  for (let i = 0; i < photos.value.length; i++) {
          photoArr.value.push(photos.value[i].imgurl);
      }
      console.log('photoArr', photoArr.value);
}

// 修改getPhotoCaed函数
const getPhotoCard = () => {
  if (photoPage.value > 0) {
    isLoading.value = -1;
    let data = {
      type: 1,
      page: photoPage.value, // 使用photoPage
      pagesize: pagesize,
      userId: user.value,
      label: numberlabel.value,
    };
    findWallPageApi(data).then((res) => {
      photos.value = photos.value.concat(res.message);
      console.log('photos', photos.value);
      if (res.message.length) {
        photoPage.value++; // 更新photoPage
      } else {
        photoPage.value = 0;
        isPhotoLoading.value = 2;
      }
      if (isLoading.value !== 2) {
        if (photos.value.length > 0) {
          isLoading.value = 1;
        } else {
          isLoading.value = 0;
        }
      }
      getPhotoArr();
    });
  }
}


//numberlabel是用来控制标签的选中状态的，-1表示没有选中，其他数字表示选中的标签的索引
const numberlabel = ref(-1);

//点击标签触发，改变numberlabel的值
const selectLabel = (index) => {
  numberlabel.value = index;
};



//nWidth的值来存放放置卡片的空间盒子的外边距的值，初始值为0
const nWidth = ref(0);

// 这个函数用来计算放置卡片的空间盒子的外边距
const noteWidth = () => {
  //Width获取当前页面宽度
  let Width = document.body.clientWidth;
  //装便签的盒子两边的外边距之和最小为120，最大为300+120
  nWidth.value = Math.floor((Width - 120) / 300) * 300;
};

//add按钮与窗口底部距离，初始值为30
const addBottom = ref(30);

//滚动条滚动时触发该函数
// 1.用来控制add按钮的位置，
// 2.用来判断是否滚动到了最底部，如果滚动到了最底部，就调用getWallCard函数，获取更多的便签数据
const scrollBottom = () => {
  //获取滚动条距离顶部的高度（相对页面框距离距离实际页面顶部的距离）
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

  //获取页面的可视高度（界面窗口的高度）
  const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;

  //获取内容高度(页面总高度)
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

  //判断（当滚动条划到最底时有 scrollTop + clientHeight = scrollHeight）
  //判断条件的意思是：当滚动条划到距离底部距离小于230px时，add按钮已经到实际界面的最底部位置
  addBottom.value =
    scrollTop + clientHeight + 230 >= scrollHeight
      ? scrollTop + clientHeight + 230 - scrollHeight
      : 30;

  //这个判断是如果滚动条到了最底部，就调用getWallCard函数，获取更多的便签数据
  if (scrollTop + clientHeight === scrollHeight) {
    id.value === 0 ? getWallCard() : getPhotoCard();
  }
};


//添加便签的标题有：添加留言时显示写留言，查看留言详情时为空
const title = ref("");
//控制弹窗，初始值为false，false表示隐藏，true表示显示
const modal = ref(false);
//控制弹窗的显示与隐藏的函数
const closeModal = () => {
  modal.value = false;
  id.value === 1 ? (view.value = false) : id.value;
};

//留言卡片的索引，初始值为-1，-1表示没有选中，其他数字表示选中的卡片的索引
const cardSelected = ref(-1);

//点击留言卡片触发的函数，改变cardSelected的值
const changeCardselected = (index) => {
  console.log('test',index);
  title.value = "";
  //选中与取消选中的逻辑
  if (index !== cardSelected.value) {
    cardSelected.value = index;
    modal.value = true;
    id.value === 1 ? (view.value = true) : id.value;
  } else {
    cardSelected.value = -1;
    modal.value = false;
    id.value === 1 ? (view.value = false) : id.value;
  }
};

//add按钮的点击事件，改变modal的值为true，显示弹窗
const addCard = () => {
  title.value = "写留言";
  cardSelected.value = -1;
  modal.value = true;
};


//监听id的值，实现页面的切换时，初始化状态
watch(id, (newVal, oldVal) => {
    modal.value = false;
    view.value = false;
    numberlabel.value = -1;
    selectLabel(-1);
  }
);

// 提交留言后，NewCard组件绑定自定义事件newCard，触发该函数，将新的留言添加到notes数组中
const newCard = (e) => {
  if (id.value === 0) {
    notes.value.unshift(e);
  } else {
    photos.value.unshift(e);
  }
  closeModal();
};


//是否预览图片
const view = ref(false);
const viewSwitch = (e) => {
  console.log(e);
  if (e === 0) {
    cardSelected.value--;
  }
  if (e === 1) {
    cardSelected.value++;
  }
};


//是否为加载状态，-1为加载中，0为没有拿到数据，1为拿到数据，2为划到底部
const isLoading = ref(1);
const isNotesLoading = ref(1); // 留言加载状态
const isPhotoLoading = ref(1); // 照片加载状态

//加载动画
// 定义 loading 函数，用于控制加载动画
const Loading = () => {
  // 检查 isLoading 的值是否为 -1，表示加载中状态
  if (isLoading.value === -1) {
    // 等待 DOM 更新完成后执行加载动画的初始化
    nextTick(() => {
      const params1 = {
        // 指定动画容器
        container: document.getElementById("lottie"),
        // 使用 SVG 渲染器
        renderer: "svg",
        // 动画循环播放
        loop: true,
        // 自动播放动画
        autoplay: true,
        // 动画数据
        animationData: loading,
      };
      // 加载并播放动画
      lottie.loadAnimation(params1);
    });
  }
};


</script>

<template>
  <div class="wall-message">
    <p class="title">{{ wallType[id].name }}</p>
    <p class="slogan">{{ wallType[id].slogan }}</p>
    <div class="label">
      <p class="label-list" :class="{ lbselect: numberlabel === -1 }" @click="selectLabel(-1)">
        全部
      </p>
      <p class="label-list" :class="{ lbselect: numberlabel === index }" v-for="(item, index) in label[id]" :key="index"
        @click="selectLabel(index)">
        {{ item }}
      </p>
    </div>
    <div class="card" :style="{ width: nWidth + 'px' }" v-show="id === 0">
      <NoteCard v-for="(e,index) in notes" :key="e.id" :notes="e" class="card-inner" :width="'288px'"
        :class="{ cardselected: index === cardSelected }" @toDetail="changeCardselected(index)"
        v-show="numberlabel === -1 || numberlabel === e.label"></NoteCard>
    </div>
    <div class="photo" v-show="id === 1">
      <PhotoCard v-for="(e,index) in photos" :key="e.id" :photo="e" class="photo-card" @toDetail="changeCardselected(index)" v-show="numberlabel === -1 || numberlabel === e.label"></PhotoCard>
    </div>

    <!-- 卡片状态 -->
    <div class="none-msg" v-show="isLoading === 0">
      <img :src="none[id].url" />
      <p>{{ none[id].msg }}</p>
    </div>

    <div class="loading" v-show="isLoading === -1">
      <div id="lottie"></div>
      <p>加载中...</p>
    </div>

    <p class="bottom-tip" v-show="isNotesLoading === 2 && id === 0">没有更多的留言...</p>
    <p class="bottom-tip" v-show="isPhotoLoading === 2 && id === 1">没有更多的图片...</p>

    <div class="add" :style="{ bottom: addBottom + 'px' }" @click="addCard" v-show="!modal">
      <span class="iconfont icon-jiahao"></span>
    </div>
    <AddModal :title="title" @close="closeModal" :isModal="modal">
      <NewCard :id="id" @closeModal="closeModal" v-if="cardSelected === -1" @clickSubmit="newCard"></NewCard>
      <!--  响应式触发机制 ：Vue无法检测数组索引变化 (notes[cardSelected])
            强制更新 ：通过 :key 绑定当前选中索引，变化时会重新创建组件 -->
      <CardDetail v-else :card="notes[cardSelected]" :photo="photos[cardSelected]" :id="id" :key="cardSelected"></CardDetail>
    </AddModal>
    <Viewer :isView="view" :photoUrl="photoArr" :nowNumber="cardSelected" @viewSwitch="viewSwitch"></Viewer>
  </div>
</template>

<style lang="less" scoped>
@import "../assets/fonts/icon/iconfont.css";

.wall-message {
  min-height: 700px;
  padding-top: 52px;

  .title {
    padding-top: 48px;
    padding-bottom: @padding-8;
    font-size: 56px;
    color: @gray-1;
    text-align: center;
    font-weight: 600;
  }

  .slogan {
    color: @gray-2;
    text-align: center;
  }

  .label {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 40px;

    .label-list {
      padding: 0 14px;
      line-height: 28px;
      height: 30px;
      margin: @padding-4;
      color: @gray-2;
      box-sizing: border-box;
      cursor: pointer;
    }

    .lbselect {
      color: @gray-1;
      font-weight: 600;
      border: 1px solid @gray-1;
      border-radius: 16px;
    }
  }

  .card {
    display: flex;
    flex-wrap: wrap;
    padding-top: 28px;
    margin: auto; //作用：盒子水平居中

    .card-inner {
      margin: 6px;
    }

    .cardselected {
      border: 1px solid #409eff;
    }
  }

  .photo {
    width: 88%;
    margin: 0 auto;
    columns: 6; //列数
    column-gap: @padding-4;
  }

  .photo-card {
    margin-bottom: @padding-4;
    break-inside: avoid;
  }

  .add {
    width: 56px;
    height: 56px;
    border-radius: 28px;
    box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.08);
    background: @gray-1;
    position: fixed;
    right: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: @tr;

    .icon-jiahao {
      font-size: 24px;
      color: @gray-10;
    }
  }

  .none-msg {
    width: 100%;
    text-align: center;
    padding-top: 80px;
    position: absolute;
    top: 350px;

    img {
      display: inline;
    }

    p {
      font-family: serif;
      font-weight: 700;
      font-size: 24px;
      color: @gray-3;
    }
  }

  .loading {
    width: 100%;
    text-align: center;

    p {
      margin-top: -72px;
      font-family: serif;
      font-size: 24px;
      color: @gray-3;
    }
  }

  #lottie {
    margin-top: 20px;
    height: 200px;
  }

  .bottom-tip {
    text-align: center;
    color: @gray-3;
    font-size: 24px;
    padding: 20px 0;
  }
}
</style>
